{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "raw_mimetype": "text/restructuredtext"
   },
   "source": [
    ".. _nb_discrete:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Discrete Variable Problem\n",
    "\n",
    "Mostly, *pymoo* was made for continuous problems, but of course, other variable types can be used as well. The genetic algorithm is a very modular class, and by modifying the sampling, crossover, and mutation (in some cases also repair), different kinds of variable types can be used (also more complicated ones such as tree, graph, ...)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the following we consider an easy optimization problem where only integer variables are supposed to be used."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Best solution found: [3 7]\n",
      "Function value: [-7]\n",
      "Constraint violation: [0.]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "from pymoo.factory import get_algorithm, get_crossover, get_mutation, get_sampling\n",
    "from pymoo.optimize import minimize\n",
    "from pymoo.model.problem import Problem\n",
    "\n",
    "\n",
    "class MyProblem(Problem):\n",
    "\n",
    "    def __init__(self):\n",
    "        super().__init__(n_var=2, n_obj=1, n_constr=1, xl=0, xu=10, type_var=np.int)\n",
    "\n",
    "    def _evaluate(self, x, out, *args, **kwargs):\n",
    "        out[\"F\"] = - np.min(x * [3, 1], axis=1)\n",
    "        out[\"G\"] = x[:, 0] + x[:, 1] - 10\n",
    "\n",
    "\n",
    "method = get_algorithm(\"ga\",\n",
    "                       pop_size=20,\n",
    "                       sampling=get_sampling(\"int_random\"),\n",
    "                       crossover=get_crossover(\"int_sbx\", prob=1.0, eta=3.0),\n",
    "                       mutation=get_mutation(\"int_pm\", eta=3.0),\n",
    "                       eliminate_duplicates=True,\n",
    "                       )\n",
    "\n",
    "\n",
    "res = minimize(MyProblem(),\n",
    "               method,\n",
    "               termination=('n_gen', 40),\n",
    "               seed=1,\n",
    "               save_history=True\n",
    "               )\n",
    "\n",
    "print(\"Best solution found: %s\" % res.X)\n",
    "print(\"Function value: %s\" % res.F)\n",
    "print(\"Constraint violation: %s\" % res.CV)\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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pMEVUdLTUjVxeE7Ch/AaXntMexH3Mbxmy94KFZWU6UBltTqmpSovJzPuplzNmDGjweMDBw6McSWhufHGG3X11Verd+/erktJaE6CuDHmlwqG8MOS1kq6oYFPp2631i6KcWkRycvJVF5OZkI80VvDrNGnadbo07SoqFRPvbVLXx+q1rHHpGrsWScl9JzwpkzI76sJ+X31yqY9WurfrYrKaqWnpWpUbs+EnRPeFK89pr2I+xheUFRSpnmrtza4kdWgrAxNiqP/cBYUFLguISyZmZlR3XHSK1yNiNektTaSbmzkmkJJi2JSTSvp3z3dU29g1+RlJW3wbsz5p/ZIyuDdGK89pr2I+xjJ6um3dmra0vcVaGQZ6A2l5Rr38HrNHnWarkygFb4OHjyoefPm6emnn1ZJSYmMMTrttNM0adIkjRkzps61VVVV+stf/qIXX3xRH3zwgfbs2aMOHTrI5/Ppd7/7nS644IJ6t//uu+9q1qxZWr9+vT799FN16tRJvXr10rnnnqs//elPatOmjaTgHPG77rpLa9eu1dChQ+vdzu7duzVlyhS98sorOnDggE499VRNnjy5Xo1N+fzzz3X33Xdr2bJl2r59u9LS0nTWWWdpypQpYc1Dj2dOgri1tkBSgYufDQAAkltRSVmTIbxGwEpTl76nE7u2j5uR8abs379fw4cP18aNG+Xz+TR+/HgFAgGtXLlSY8eO1ebNm+uMrO/bt0833nijzjnnHP34xz/Wcccdp08//VR///vfdeGFF+qRRx7RNddcU3v9O++8oyFDhqhNmza69NJL1adPH3311VfaunWr7r//fs2aNas2iDfl888/1znnnKPMzEyNHz9e+/fv15IlSzR27Fh98sknuummm5q9jdLSUg0fPlw7duzQueeeq4suukgVFRVasWKFzj//fD388MO69tprI/lnjCvs0gAAAJLKvNVbmw3hNQJWmr96q/Mg3tDUlD59+tQJyv/1X/+ljRs36p577tHNN99ce/ybb77RpZdeqttvv12jR4/WD37wA0nB6SM7d+7UiSfWXXTgiy++0JAhQzR58mRdddVVateunSRp0aJFqqqq0ooVKzRy5Mg6bcrLy2uva867776rq666Sk888UTtxjhTpkyRz+fT1KlTNWrUqGbnlo8bN047d+7UkiVLdMUVV9Qe379/v84991xNnDhRF198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UP/+/bV8+XLXpTTqxBNP1ObNm9W5c2fXpcQFgngLzFu9tdk37xoBK81fvTWh38AXvFYS9vUEccQ7rz2PAU/ZtkYqvFvaUVT/XO88Kf8WKXtYjIuKnk8++UTnnnuu6zKa1LZtW5188smuy4gbrJoSoS17KxqcS9qU9aXl2rK3IkoVRdcrm/bUmxPenIrKar2yaU+UKgJazmvPY8BT/I9Liy9vOIRLweOLL5f8i2NbVwi2b98uY4yuueYabd++XWPHjlVmZqbS0tJ05plnasWKFXWuHzZsmIwxstaqsLBQxhgZYzRs2LA617388su66KKLlJmZqXbt2qlv376aPHmyvvjii3o1vPbaa/r1r3+tU045RZ06dVL79u31/e9/XzNnzlRlZWW96ysqKnTHHXfo+9//vjp16qT09HT17dtXY8aMUXFxcYN9a0ggENC9996rk08+WWlpaerZs6duuukmffXVV2H9Gz755JMaPny4unTporS0NA0YMEB33nmnqqqqwrqdaGNEPEJFJWURt0vEFRiW+ndH3I6VVBCvvPY8Bjxj2xpp+STJBpq+zgak5TdIXU6Ky5HxHTt2aNCgQcrOzta4ceNUXl6up59+WpdddplWrVql4cOHSwp+0HHYsGGaOXOmevfuXRtyj/7Q48yZM1VQUKCMjAxdfPHFOv744/Xee+/pT3/6k1588UW98cYb6tSpU+31f/zjH/Xhhx/qnHPO0ciRI1VZWamioiIVFBRozZo1WrVqldq0aSMpOL/9Jz/5if75z39qyJAh+tWvfqXU1FTt3r1br732mn74wx/K5/OF1OebbrpJr7/+uq688kpddtllevnllzV37lytXbtW69atU1paWrO3MX78eD366KPq2bOnRo8erS5duujNN9/U9OnTtXr1av3jH/9Qamp8ROD4qCIBHQhzdLil7VwLdzS8pe2AWPDa8xjwjMK7mw/hNWxAKpwTl0F8zZo1Kigo0IwZM2qP/fznP9dPfvITzZkzp04Ql4Jhu0+fPiooKKhzO6+99poKCgo0ZMgQvfjii+rSpUvtuUWLFunaa6/VjBkzdN9999Uef+CBB5SVlVX7YdIa06dP15133qlnn31WY8aMkST961//0j//+U/99Kc/1fPPP1/n+kAgoC+//DLkPhcVFendd99V7969JUmzZs3SFVdcoaVLl2rOnDmaPn16k+0XLVqkRx99VJdffrmeeOIJtW/fvvZcQUGBZs6cqfvvv1+TJk0KuaZoYmpKhDqmRfZ/mEjbuZYeYd2RtgNiwWvPY8ATPtvc+HSUxuxYF2wXZ3r37q3bbrutzrELLrhAvXr10oYNG0K+nfnz50uSHnrooTohXAqG+IEDB+qJJ56oczw7O7teCJeCI9ZScJrLdx0demukpKSoa9euIdc6adKk2hBe037OnDlKSUnRI4880mz7efPmKTU1VY888ki9eqZPn65u3brV66tLvJtEKNIPayXqh7xG5fbUyk17I2oHxCuvPY8BT9hWGHm7OFtJZeDAgbXTP4520kkn6Y033gj5dt544w21bdtWzzzzjJ555pl65w8dOqR9+/bp888/V7du3SRJBw8e1Lx58/T8889ry5YtqqioqLPE4scf//9V1E455RQNHDhQTz75pHbs2KHLLrtMQ4cO1ZlnnqljjjkmnC4rPz+/3rHs7GyddNJJ2r59u7744ot6/5mo8fXXX2vjxo3KzMzU3LlzG7ymXbt22rw5fv7TRRCPUP/u6RqUlRHWB70GZ2Uk7LzS80/tofS01LCmmqSnpTI/HHHNa89jwBOqIvwwdaTtoqixwJmamqpAIMSpN5I+//xzVVdXa+bMmU1ed+DAAXXr1k3ffvutzjvvPG3YsEHf//73NWbMGB133HFq27atpOAUmKM/9NimTRu9+uqruv322/Xss89qypQpkqT09HT98pe/1KxZs9SxY8eQau3evXuDx3v06KEdO3boyy+/bPTfZf/+/bLWat++fc32NV4wNaUFJo3op5T6v7VpUIqRbhjRL7oFRdnE4TlRvR5wwWvPYyDptYvwP8qRtksAnTt3VteuXWWtbfJPzZSQZcuWacOGDbrmmmv0/vvv6y9/+YvuuusuFRQUaMKECQ3+jK5du+q+++7Trl27tHXrVv31r3/VySefrAULFug//uM/Qq51796Gf/u+Z8+e2r401U9JOuOMM5rta7wgiLdAXk6mZo36QbNv4ilGmj3qtIT/dfaE/L4anXtiSNde4evJGuJICF57HgNJL7v+1IaotksAZ599tvbv369NmzaFdH1JSXDfkFGjRtU7V1jY/NSfnJwcXXfddSosLFTHjh21bNmykGtt6Pa3bdumXbt2qU+fPo2OhktSx44ddeqpp2rTpk0qLw9vaVpXCOIt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vo6qa31FJWWat3qrNpSW1zs3KCtDk0b0U14Ov+oCAMRex2M6xrRdNHXp0kXf+9735Pf75ff7ddJJJ6lz586SpDPOOEN+vz/k2xo5cqRGjhypgwcPav369VqxYoX+/Oc/6+KLL9Y777yjU045JVrdQBOcLV9ojOkrqVjStZI2SLpP0jZJkyS9YYzp5qq2cPx2ybua9dKH9UJ4jYrKas166UNNfmZjjCuLjqff2qlxD69vMIRL0obSco17eL2WvLUrxpUBACAN7jE4pu2ibf/+4LhkIBD88GnHjh116qmnatOmTSovb/i9uCkdOnTQeeedp3vvvVe33nqrDh06pJdeeqn2fJs2bSRJhw8fboXq0RyX64g/IOl4STdYa39qrZ1qrT1PwUD+PUl3OawtJAsLP9Jz/o9DuvaZ4t1aWPhRlCuKrqKSMk1b+r4CtunrAlaauvQ9FZWUXzXKSwAADdhJREFUNX0hAACtLKdrjnzdfWG1ObP7mXG306Yk/e1vf1Npaanatm2rc845p/b4zTffrEOHDmn8+PH64osv6rXbv39/ndHy119/XdXV9QcM9+7dK0k69thja4916xYcB925c2er9QONczI15cho+PmStku6/zunZ0j6taRxxpjfWmsPxri8kC14rSTs6xN5isq81VubDeE1Alaav3orU1QAADH3m9N/own/mBDSEoYpJkUTTp8Qg6qadvTyhQcPHtQHH3xQO1L9hz/8Qd27d689P378eBUXF+uBBx5Q3759dcEFF6hXr14qLy9XaWmpXn/9dV177bV68MEHJUk33HCDPv74Y+Xl5alPnz465phjVFxcrFdffVW9e/fW2LFja297xIgRmjNnjq6//nqNHj1a6enp6tKliyZOnBibfwiPcTVHfPiRr69YW/dZYq2tMMYUKRjUz5a0OtbFheKVTXsanY7SmIrKar2yaU9CfoBzy96KRqejNGZ9abm27K3gA5wAgJg6+4SzNWPIjGY39UkxKSoYUuB8DXGp7vKFbdq00XHHHadLLrlEEydObPDDlPfff78uvPBCPfjgg1q1apW++OILZWRkqFevXpo8ebKuvvrq2mtvvfVWPf/883r77be1atUqpaSkqFevXrr11lt14403qmvXrrXXXnDBBbrnnnv00EMPae7cuTp06JB69+5NEI8SV0H8e0e+bmnk/FYFg3h/NRHE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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "image/png": {
       "height": 248,
       "width": 369
      },
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "from pymoo.util import plotting\n",
    "\n",
    "_X = np.row_stack([a.pop.get(\"X\") for a in res.history])\n",
    "feasible = np.row_stack([a.pop.get(\"feasible\") for a in res.history])[:, 0]\n",
    "\n",
    "plotting.plot(_X[feasible], _X[np.logical_not(feasible)], res.X[None,:]\n",
    "              , labels=[\"Feasible\", \"Infeasible\", \"Best\"])"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
